package com.mysteel.cyx.demo.biz.export;

import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

/**
 * 自适应高度调整器
 */
public class CustomRowHeightHandler implements RowWriteHandler {

    @Override
    public void afterRowDispose(RowWriteHandlerContext context) {
        Row row = context.getRow();
        Sheet sheet = row.getSheet();

        float maxHeight = row.getHeightInPoints(); // Default row height
        for (int cellNum = 0; cellNum < row.getLastCellNum(); cellNum++) {
            Cell cell = row.getCell(cellNum);
            if (cell != null) {
                float cellHeight = calculateCellHeight(cell, sheet);
                if (cellHeight > maxHeight) {
                    maxHeight = cellHeight;
                }
            }
        }

        row.setHeightInPoints(maxHeight);
    }

    private float calculateCellHeight(Cell cell, Sheet sheet) {
        String cellValue = getCellStringValue(cell);
        if (cellValue == null || cellValue.isEmpty()) {
            return sheet.getDefaultRowHeightInPoints();
        }

        DataFormatter dataFormatter = new DataFormatter();
        String formattedValue = dataFormatter.formatCellValue(cell);

        // Assuming a fixed width font, calculate cell height
        float defaultCharWidth = 7.5f; // Approximate character width
        int maxLineLength = (int) (sheet.getColumnWidth(cell.getColumnIndex()) / 256 * defaultCharWidth);

        // Calculate number of lines needed for the content
        int lines = (int) Math.ceil((double) formattedValue.length() / maxLineLength);

        return lines * sheet.getDefaultRowHeightInPoints();
    }

    private String getCellStringValue(Cell cell) {
        switch (cell.getCellType()) {
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    return String.valueOf(cell.getNumericCellValue());
                }

            case STRING:
                return cell.getStringCellValue();
            case FORMULA:
                return cell.getCellFormula();
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            default:
                return StringUtils.EMPTY;
        }
    }
}
